/**
 * 登录控制器
 */

const Users = require('../../../models/user.model');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { body, validationResult } = require('express-validator');
const jwtConfig = require('../../../config/jwt.config');

/**
 * 生成JWT令牌
 * @param {Object} user - 用户对象
 * @returns {Object} - 包含访问令牌和刷新令牌的对象
 */
const generateTokens = (user) => {
    // 创建JWT payload
    const payload = {
        id: user._id,
        email: user.email,
        userName: user.userName
    };

    // 生成访问令牌
    const accessToken = jwt.sign(payload, jwtConfig.secret, { expiresIn: jwtConfig.expiresIn });

    // 生成刷新令牌（可选）
    const refreshToken = jwt.sign({ id: user._id }, jwtConfig.secret, { expiresIn: jwtConfig.refreshExpiresIn });

    return {
        accessToken,
        refreshToken
    };
};

/**
 * 处理用户登录
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - Express下一个中间件
 */
const login = [
    // 1. 验证层 (保持不变，很棒)
    body('email').isEmail().normalizeEmail().withMessage('请输入有效的邮箱地址'),
    body('password').notEmpty().withMessage('密码不能为空'),

    // 2. 逻辑处理层
    async (req, res, next) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() });
        }

        try {
            const { email, password } = req.body;

            // 查找用户
            const user = await Users.findOne({ email });
            if (!user) {
                return res.status(402).json({ message: '用户不存在;请先注册' });
            }
            // 使用短路求值来安全地比较密码
            const isPasswordValid = user ? await bcrypt.compare(password, user.password) : false;
            if (!isPasswordValid) {
                return res.status(401).json({ message: '邮箱或密码不正确' });
            }


            // 生成令牌
            const tokens = generateTokens(user);
            res.status(200).json({
                message: '登录成功',
                accessToken: tokens.accessToken,
                refreshToken: tokens.refreshToken,
                user: {
                    id: user._id,
                    email: user.email,
                    userName: user.userName
                }
            });
        } catch (error) {
            next(error);
        }
    }
];

/**
 * 刷新访问令牌
 */
const refreshToken = async (req, res, next) => {
    try {
        const authHeader = req.headers.authorization;
        let refreshToken;

        if (authHeader && authHeader.startsWith('Bearer ')) {
            refreshToken = authHeader.substring(7);
        }

        if (!refreshToken) {
            return res.status(400).json({ message: '刷新令牌不能为空或格式不正确' });
        }

        // 验证刷新令牌
        jwt.verify(refreshToken, jwtConfig.secret, async (err, decoded) => {
            if (err) {
                return res.status(401).json({ message: '刷新令牌无效或已过期' });
            }

            // 查找用户
            const user = await Users.findById(decoded.id);
            if (!user) {
                return res.status(404).json({ message: '用户不存在' });
            }

            // 生成新的令牌
            const tokens = generateTokens(user);

            // 返回新的令牌
            res.json({
                accessToken: tokens.accessToken,
                refreshToken: tokens.refreshToken
            });
        });
    } catch (error) {
        error.message = "刷新令牌失败";
        next(error);
    }
};

const register = [
    body('email').isEmail().withMessage('请输入有效的邮箱地址'),
    body('password').isLength({ min: 6 }).withMessage('密码必须至少包含6个字符'),
    body('userName').isLength({ min: 2 }).withMessage('用户名必须至少包含2个字符'),
    async (req, res, next) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() });
        }
        try {
            const { email, password, userName } = req.body;
            const existingUser = await Users.findOne({ email });
            if (existingUser) {
                return res.status(400).json({ code: 400, message: '用户已存在' });
            }
            const hashedPassword = await bcrypt.hash(password, 10);
            const user = await Users.create({ email, password: hashedPassword, userName });
            res.json({ status: 201, message: '注册成功' });
        } catch (err) {
            err.message = "注册失败";
            next(err);
        }
    }
]

module.exports = {
    login,
    register,
    refreshToken
}; 